home *** CD-ROM | disk | FTP | other *** search
- /*
-
- G R A F I X . C
-
- VERSION : 3.0
- EDIT-DATE : 25-Oct-87
-
-
- My own Int. 10h driven BIOS ROM graphics routines. These will only
- work on the IBM-PC or compatable; and are recommended for use only
- with Microsoft 'C' Version 4.00 or later under MS-DOS 3.10 or later.
-
- M O D I F I C A T I O N H I S T O R Y
-
- VERSION DESCRIPTION
- ------- -----------
- 1.0 Creation, supports CGA modes 4, 5 and 6 only. No EGA
- modes supported.
-
- 2.0 Added support for EGA modes 0Dh and 0Eh (13 and 14)...
- 320 X 200 with 16 colors and 640 X 200 with 16 colors.
-
- 2.1 Changed the save_pic() and load_pic()| functions to make
- them "smarter"; as well as save additional information.
- Although this information may be somewhat specific to the
- PLOTFRAC program, the information may be useful to other
- applications.
-
- 3.0 Added the support for EGA mode 10h (16)...
- 640 X 350. This mode requires not only an EGA card, but
- also an Enhanced Color Display (ECD) -- a.k.a. EGA monitor
- or a Multi-Sync monitor.
-
- */
-
- #include <dos.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #include <float.h>
-
- #define ROM_BIOS 0x10 /* INT 10H calls the IBM-PC ROM
- BIOS video driver services */
-
- #define DOS_INT 0x21 /* MS-DOS Int. 21h service call */
-
- #define PRN_OUTPUT 0x05 /* Function 05h sends output to PRN: */
-
- #define SET_VI_MODE 0x00 /* Function 00h sets the video mode
- calls. */
-
- #define SET_PALETTE 0x0B /* Function 0Bh sets the color
- palette for 320 X 200 medium-res */
-
- #define WRITE_PIXEL 0x0C /* Function 0Ch writes a pixel at
- location specified by CX & DX */
-
- #define READ_PIXEL 0x0D /* Function 0Dh reads a pixel at
- location specified by CX & DX */
-
- #define GET_DIS_MODE 0x0F /* Function 0Fh gets the current
- display mode and saves all the
- relevant information. */
-
- #define SELECT_PAGE 0x05 /* Function 05h selects the current
- active display page */
-
- extern void get_mode (void);
- extern void set_mode (int);
- extern void set_palette (int);
- extern void set_background (int);
- extern void plot_point (int, int, int);
- extern void set_page (int);
- extern void save_pic (char *, double *, int *);
- extern void load_pic (char *);
- extern int read_point (int, int);
- extern void print_pic (void);
- extern void prn_out (int);
-
- FILE *PIC_STREAM;
-
- union REGS inregs, outregs;
- struct SREGS segregs;
-
- char P_BUFFER[350];
- int bits[8] = {1,2,4,8,16,32,64,128};
-
- int CURRENT_PAGE = 0, CURRENT_MODE = 0, PALETTE = 0, BACKGROUND = 0,
- USE_MODE = 0;
-
- void get_mode()
- {
- register int i;
- int result;
-
- for (i=0;i<350;i++)
- P_BUFFER[i] = 0;
- inregs.h.ah = GET_DIS_MODE;
- result = int86x(ROM_BIOS, &inregs, &outregs, &segregs);
- CURRENT_PAGE = outregs.h.bh;
- CURRENT_MODE = outregs.h.al;
-
- } /* End of GET_MODE */
-
- void set_mode(mode_val)
- int mode_val;
- {
- int result;
-
- USE_MODE = mode_val;
- inregs.h.ah = SET_VI_MODE;
- inregs.h.al = mode_val;
- result = int86x(ROM_BIOS, &inregs, &outregs, &segregs);
-
- } /* End of SET_MODE */
-
- void set_palette(palette_val)
- int palette_val;
- {
- int result;
-
- if (USE_MODE == 0x06 || USE_MODE == 0x0D || USE_MODE == 0x0E)
- return;
- PALETTE = palette_val;
- inregs.h.ah = SET_PALETTE;
- inregs.h.bh = 1;
- inregs.h.bl = palette_val;
- result = int86x(ROM_BIOS, &inregs, &outregs, &segregs);
-
- } /* End of SET_PALETTE */
-
- void set_background(background_val)
- int background_val;
- {
- int result;
-
- if (USE_MODE == 0x06 || USE_MODE == 0x0D || USE_MODE == 0x0E)
- return;
- BACKGROUND = background_val;
- inregs.h.ah = SET_PALETTE;
- inregs.h.bh = 0;
- inregs.h.bl = background_val;
- result = int86x(ROM_BIOS, &inregs, &outregs, &segregs);
-
- } /* End of SET_BACKGROUND */
-
- void plot_point(x_val, y_val, plot_color)
- int x_val, y_val, plot_color;
- {
- int result, max_col, max_row;
-
- max_row = 199;
- switch (USE_MODE) {
- case 4: /* 320 X 200, 4 color */
- case 5: /* 320 X 200, 4 color (burst off) */
- case 13: /* 320 X 200, 16 color (EGA) */
- max_col = 319;
- break;
- case 6: /* 640 X 200, 2 color */
- case 14: /* 640 X 200, 16 color (EGA) */
- case 16: /* 640 X 350, 16 color (EGA) */
- max_col = 639;
- if (USE_MODE == 16)
- max_row = 349;
- break;
- }
- if (x_val < 0 )
- x_val = 0;
- if (x_val > max_col)
- x_val = max_col;
- if (y_val < 0)
- y_val = 0;
- if (y_val > max_row)
- y_val = max_row;
-
- inregs.h.ah = WRITE_PIXEL;
- inregs.h.al = plot_color;
- inregs.x.cx = x_val;
- inregs.x.dx = y_val;
- result = int86x(ROM_BIOS, &inregs, &outregs, &segregs);
-
- } /* End of PLOT_POINT */
-
- void set_page(page_num)
- int page_num;
- {
- int result;
-
- inregs.h.al = SELECT_PAGE;
- inregs.h.al = page_num;
- result = int86x(ROM_BIOS, &inregs, &outregs, &segregs);
-
- } /* End of SET_PAGE */
-
- int read_point(n_col,n_row)
- int n_col, n_row;
- {
- int result;
-
- inregs.h.ah = READ_PIXEL;
- inregs.x.cx = n_col;
- inregs.x.dx = n_row;
- result = int86x(ROM_BIOS, &inregs, &outregs, &segregs);
- return (outregs.h.al);
-
- } /* End of READ_POINT */
-
- void save_pic(save_fname, xy_data, gr_data)
- char *save_fname;
- double *xy_data;
- int *gr_data;
- {
- int wr_result, row_num, col_num, max_col, p_num, max_row;
-
- max_row = 199;
- switch (USE_MODE) {
- case 4:
- case 5:
- case 13:
- max_col = 320;
- break;
- case 6:
- case 14:
- case 16:
- max_col = 640;
- if (USE_MODE == 16)
- max_row = 349;
- break;
- }
-
- PIC_STREAM = fopen(save_fname,"w+b");
-
- /*
- First let us save the following information:
- xy_data - The minimum and maximum X-Y or P-Q values
- gr_data - The resolution of the plot (320 or 640, and 200 or 350) and
- the grafix mode used
- */
- wr_result = fwrite((char*)xy_data, sizeof(double),4,PIC_STREAM);
- wr_result = fwrite((char*)gr_data, sizeof(int),3,PIC_STREAM);
-
- /*
- Now save the picture, one column at a time.
- */
- for (col_num=0;col_num<max_col;col_num++) {
- for (row_num=0;row_num<max_row+1;row_num++) {
- p_num = (read_point(col_num,row_num) + 32);
- P_BUFFER[row_num] = p_num;
- }
- wr_result = fwrite((char *)P_BUFFER,sizeof(char),max_row+1,PIC_STREAM);
- }
- fclose(PIC_STREAM);
-
- } /* End of SAVE_PIC */
-
- void load_pic(save_fname)
- char *save_fname;
- {
- int seek_result, row_num, col_num, max_col, max_row;
- int gr_stuf[3];
- double xy_stuf[4];
-
- max_row = 199;
- switch (USE_MODE) {
- case 4:
- case 5:
- case 13:
- max_col = 320;
- break;
- case 6:
- case 14:
- case 16:
- max_col = 640;
- if (USE_MODE == 16)
- max_row = 349;
- break;
- }
-
- PIC_STREAM = fopen(save_fname,"r+b");
- seek_result = fseek(PIC_STREAM,0L,SEEK_SET);
-
- /*
- This routine reads the "file heading" info saved by save_pic(); but
- doesn't do anything with it since all of that is handled currently
- within the PLOTFRAC main routine restore_picture(). This will be
- changing with the next version of GRAFIX.
- */
- seek_result = fread((char*)xy_stuf,sizeof(double),4,PIC_STREAM);
- seek_result = fread((char*)gr_stuf,sizeof(int),3,PIC_STREAM);
-
- /*
- Now read the picture one column at a time and restore it.
- */
- for (col_num=0;col_num<max_col;col_num++) {
- seek_result = fread((char *)P_BUFFER,sizeof(char),max_row+1,PIC_STREAM);
- for (row_num=0;row_num<=max_row;row_num++) {
- plot_point(col_num,row_num,((int)P_BUFFER[row_num] - 32));
- }
- }
-
- fclose(PIC_STREAM);
-
- } /* End of LOAD_PIC */
-
- void print_pic()
- {
- int pr_num, row_num, col_num, max_col, pix_val, row_offset, max_offset,
- max_row;
-
- max_row = 199;
- if (USE_MODE == 4 || USE_MODE == 5 || USE_MODE == 13)
- max_col = 320;
- else {
- max_col = 640;
- if (USE_MODE == 16)
- max_row = 349;
- }
- max_offset = 4;
-
- prn_out(27); /* <ESC> */
- prn_out((int)'A'); /* "A" */
- prn_out(8); /* <BS> */
- for (row_num=0;row_num<max_row+1;row_num+=max_offset) {
- prn_out(27); /* <ESC> */
- prn_out((int)'*'); /* "*" */
- prn_out(4); /* chr$(4) */
- prn_out(128); /* n1 = 128 */
- prn_out(2); /* n2 = 2 Graphic number = 128 + 512 = 640 */
- /* Set Graphic Print Mode 1:0.9 Vert.:Horiz. */
- for (col_num=0;col_num<max_col;col_num++) {
- pr_num = 0;
- for (row_offset=0;row_offset<max_offset;row_offset++) {
- pix_val = read_point(col_num, (row_num+row_offset));
- if (pix_val == 0) {
- pr_num = (pr_num | bits[7 - (2 * row_offset)]);
- pr_num = (pr_num | bits[6 - (2 * row_offset)]);
- }
-
- } /* Next row_offset */
- prn_out(pr_num); /* Print the graphics block needed */
- if (USE_MODE == 4 || USE_MODE == 5 || USE_MODE == 13)
- prn_out(pr_num); /* Print it again if we're in 320 x 200 */
-
- } /* Next col_num */
- prn_out(10); /* <LF> */
-
- } /* Next row_num */
- prn_out(12); /* <FF> */
-
- } /* End of PRINT_PIC */
-
- void prn_out(out_char)
- int out_char;
- {
- int result;
-
- inregs.h.ah = PRN_OUTPUT;
- inregs.h.dl = (char)out_char;
-
- result = int86x(DOS_INT, &inregs, &outregs, &segregs);
-
- } /* End of PRN_OUT */
-